home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / N-P / PixelFlipper src / Sources / FlipperUtils.c next >
Encoding:
C/C++ Source or Header  |  1990-12-05  |  10.8 KB  |  285 lines  |  [TEXT/KAHL]

  1. /*
  2.     FlipperUtils.c
  3.     written in Think C 4.0 by Chris Sanchez
  4.     Copyright ©1990 Chris Sanchez, All Rights Reserved
  5. */
  6.  
  7. #include    "PixelFlipper.h"
  8. #include    "FlipperUtils.h"
  9.  
  10. /**********************************************************************************************
  11.                                                     Private Routines for the Utilities
  12. **********************************************************************************************/
  13. static Boolean WritePref(HParmBlkPtr  h, PREFPtr p)
  14. /*    ->    h, p.  h is the parameter block that contains the information about the file
  15.                 that we are going to save the preferences to.  p is the preferences that are to be saved.
  16.         <-    Boolean. If the operation was successful, then it will return TRUE, else
  17.                  it will report the error and return false.
  18. */
  19. {
  20.     h->ioParam.ioPosOffset = 0;
  21.     h->ioParam.ioBuffer = p;
  22.     if (!CheckError(PBWrite(h, FALSE), noErr, kCreating)) return FALSE;    /* space has been allocated    */
  23.     if (PBGetEOF(h, FALSE) != noErr) return FALSE;        /* get the eof                            */
  24.     if (PBSetEOF(h, FALSE) != noErr) return FALSE;        /* set the eof                            */
  25.     FlushVol( NIL, h->fileParam.ioVRefNum);
  26.     return TRUE;    
  27. }
  28.  
  29. static Boolean Find1File(short    *theRefNum,long *theDir, char    *fileName, Boolean directory)
  30. /*    ->    theRefNum, theDir, fileName, directory. directory specifies whether the routine is
  31.                 searching for a directory (folder) or a file. If directory is TRUE, then theRefNum
  32.                 is a working directory number and theDir is NUL upon entry.
  33.                 Otherwise, theRefNum is a volume reference number and theDir is a directory ID.
  34.         <-    If we were searching for a directory, then theDir will contain the directory ID
  35.                 of the requested directory and the function will return a TRUE as the result of the search.
  36.                 Otherwise, theDir will contain the file's parent directory ID. Similarly, TRUE will
  37.                 be returned as the function result.
  38.                 If the file wasn't found, then the function will return FALSE.
  39. */
  40. {    short                count=1;
  41.     CInfoPBRec    ciPB;
  42.     char                fname[33];
  43.     Str255            altStr;
  44.  
  45.     ClearPointer(&ciPB, sizeof(ciPB));
  46.     ciPB.dirInfo.ioNamePtr = fname;
  47.     while (TRUE){        /* loop until fnfErr */
  48.         ciPB.dirInfo.ioFDirIndex = count++;
  49.         ciPB.dirInfo.ioVRefNum = *theRefNum;
  50.         if (!directory)
  51.             ciPB.hFileInfo.ioDirID = *theDir;
  52.         else
  53.             ciPB.dirInfo.ioDrDirID = NIL;
  54.         if (PBGetCatInfo(&ciPB,FALSE) != noErr)                                /* if err return (reached end of dir) */
  55.             return FALSE;
  56.         if (IUCompString(fname, fileName) == 0){                            /* is this the file we wanted */
  57.                 if (ciPB.dirInfo.ioFlAttrib & 0x10){                            /* is it a directory */
  58.                     *theDir = ciPB.dirInfo.ioDrDirID;                                /* return its directory id */
  59.                     if (!directory)                                                                    /* is this a file rather than a directory */
  60.                         return Find1File(theRefNum, theDir, fileName, directory); /* then we found the file in this dir */
  61.                     else
  62.                         return TRUE;
  63.                 }else                                                                                            /* it is a file */
  64.                     if(directory){                                                                    /* a file was found with the same name as the directory we are trying to find */
  65.                         GetIndString(altStr, kStrPixel, kAltDesig);
  66.                         pStrcat(fileName, altStr);
  67.                         return Find1File(theRefNum, theDir, fileName, directory); /* then we found the file in this dir */
  68.                     }else
  69.                         *theDir = ciPB.hFileInfo.ioFlParID;                        /* return its parents directory id */
  70.             return TRUE;
  71.         }
  72.     }
  73. }
  74. /**********************************************************************************************
  75.                                                 Public Routines for PixelFlipper INIT & cdev
  76. **********************************************************************************************/
  77. Boolean Get_Set_Prefs(PREFRec *p, short theVRef, Boolean writing)
  78. /*    ->    p, theVRef.  p is the preferences that are to be gotten from the preferences file.
  79.                 theVRef is the working directory reference number that the INIT is in.
  80.         <-    Boolean. If the operation was successful, then it will return TRUE, else
  81.                  it will report the error and return false.
  82. */
  83. {    HParamBlockRec    h;
  84.     short                prefVol = theVRef;
  85.     OSErr                err;
  86.     Str255            prefName, prefDirName, tempStr;
  87.     char                found = FALSE;
  88.     long                prefDirID;
  89.     StringHandle s1;
  90.     VersRecHdl    v;
  91.     
  92.     GetIndString(prefName, kStrPixel, kPrefFile);
  93.     if (s1 = GetString(kStrFolder)){                /* this is the prefs dirID string */
  94.         pStrcpy(prefDirName, *s1);
  95.         StringToNum(prefDirName, &prefDirID);
  96.         ReleaseResource(s1);
  97.         if (GetVol(NIL, &prefVol) == noErr){                /* if this is the dirID, then we have to also get the volRefNum */
  98.             ClearPointer(&h, sizeof(HParamBlockRec));    /* No errors, then open the file. */
  99.             h.ioParam.ioNamePtr = prefName;
  100.             h.ioParam.ioVRefNum = prefVol;
  101.             h.fileParam.ioDirID = prefDirID;
  102.             h.ioParam.ioPermssn = fsRdWrPerm;
  103.             if (PBHOpen(&h, FALSE) == noErr)
  104.                 found = TRUE;
  105.             else
  106.                 prefVol = theVRef;            /* Reset the prefVol to the working dirID    */
  107.         }else
  108.             prefVol = theVRef;                /* same thing here */
  109.     }
  110.     
  111.     if(!found){        /* The dirID wasn't found */
  112.         GetIndString(prefDirName, kStrPixel, kPrefDir);
  113.         if (!Find1File(&prefVol, &prefDirID, (char *)prefDirName, TRUE))    /* look for the preferences folder */
  114.             if (DirCreate(theVRef, NIL, prefDirName, &prefDirID) != noErr)
  115.                 return FALSE;    /* bow out because we weren't able to create a preferences folder */
  116.  
  117.         /* we have a preferences folder at this point */
  118.         if (!Find1File(&prefVol, &prefDirID, (char *)prefName, FALSE))    /* look for the PixelFlipper preferences file */
  119.             if (HCreate(prefVol, prefDirID, prefName, kOurCreat, kPrefType) != noErr)
  120.                 return FALSE;    /* bow out because we weren't able to create a preferences file */
  121.         ClearPointer(&h, sizeof(HParamBlockRec));
  122.         h.ioParam.ioNamePtr = prefName;
  123.         h.ioParam.ioVRefNum = prefVol;
  124.         h.fileParam.ioDirID = prefDirID;
  125.         h.ioParam.ioPermssn = fsRdWrPerm;
  126.         if (!CheckError(PBHOpen(&h, FALSE), opWrErr, kOpeningPr)){
  127.             return FALSE;        
  128.         }
  129.     }
  130.     /* no errors opening so continue */
  131.     h.ioParam.ioReqCount = sizeof(PREFRec);
  132.     h.ioParam.ioBuffer = p;        /* this is what we return the data in */
  133.     h.ioParam.ioPosMode = fsFromStart;
  134.     h.ioParam.ioPosOffset = 0;
  135.  
  136.     if (writing){            /* we are writing out the preferences out */
  137.         if (!WritePref(&h, p)){        /* we weren't able to read the proper number of bytes in */
  138.             PBClose(&h, FALSE);
  139.             return  FALSE;
  140.         }
  141.     }else{        /* we are reading in the preferences */
  142.         err = PBRead(&h, FALSE);
  143.         if ((err != eofErr) && (err != noErr)){
  144.             PBClose(&h, FALSE);
  145.             return  FALSE;
  146.         }
  147.     }
  148.     /* no errors reading so continue */
  149.     if ((h.ioParam.ioActCount != sizeof(PREFRec)) && !writing){ /* wrong number of bytes read / written    */;
  150.         p->isPerm = FALSE;
  151.         p->showIcon = TRUE;
  152.         p->hotKey = optionKey + shiftKey;
  153.         if(v = (VersRecHdl)Get1Resource('vers', 1)){
  154.             pStrcpy(p->ver, (**v).message);
  155.             ReleaseResource(v);
  156.         }else                    
  157.             pStrcpy(p->ver, "\punknown");
  158.         p->active = TRUE;
  159.         if (!WritePref(&h, p)){        /* we weren't able to read the proper number of bytes in */
  160.             PBClose(&h, FALSE);
  161.             return  FALSE;
  162.         }
  163.     }
  164.     if (!CheckError(PBClose(&h, FALSE), noErr, kSaving)) return  FALSE;
  165.  
  166.     if (!writing)
  167.         if (s1 = Get1Resource('STR ', kStrFolder)){        /* this is the directory ID of the prefs file */
  168.             NumToString(prefDirID, tempStr);
  169.             if (IUCompString(*s1, tempStr) != 0){
  170.                 SetString(s1, tempStr);
  171.                 ChangedResource(s1);
  172.                 UpdateResFile(CurResFile());
  173.             }
  174.             ReleaseResource(s1);
  175.         }else{    /* we couldn't find the 'STR ' resource */
  176.             NumToString(prefDirID, tempStr);
  177.             if (s1 = NewString(tempStr)){
  178.                 AddResource(s1, 'STR ', kStrFolder, nullStr);
  179.                 UpdateResFile(CurResFile());
  180.                 DisposHandle(s1);
  181.             }/*else  -- we can't use the 'STR ' resource for some reason, and we will have to search for the file each t1me */
  182.         }    
  183.     
  184.     return TRUE;    /* viola, no problems */
  185. }
  186.  
  187. void PosWindow(WindowPtr theWind, GDHandle gDev)
  188. /*    ->     theWind, gDev,  The wind is the window we want to position.  gDev is 
  189.                 the graphics device we want to position the window in.  We don't want to
  190.                 position the window across different graphics devices.
  191.         <-    nothing is returned.
  192. */
  193. {        short        h,v;
  194.  
  195.         h = (((**gDev).gdRect.right - (**gDev).gdRect.left)/2) - ((theWind->portRect.right - theWind->portRect.left)/2);
  196.         v = (((**gDev).gdRect.bottom - (**gDev).gdRect.top)/2) - ((theWind->portRect.bottom - theWind->portRect.top)/2);
  197.         MoveWindow(theWind, h, v,TRUE);
  198.         ShowWindow(theWind);
  199.         SelectWindow(theWind);
  200.         SetPort(theWind);
  201. }
  202.  
  203. void pStrcat(unsigned char *dest, unsigned char *src)
  204. /*    ->     dest, src. Concatenates src to the end of dest
  205.         <-    returns the resulting string and changes dest.
  206. */
  207. {    long sLen = MIN(*src, 255 - *dest);
  208.  
  209.     BlockMove(src + 1, dest + *dest + 1, sLen);
  210.     *dest += sLen;
  211. }
  212.  
  213. void pStrcpy(unsigned char *dest, unsigned char *src)
  214. /*    ->     dest, src. Copies src into dest
  215.         <-    returns the resulting string and changes dest.
  216. */
  217. {
  218.     BlockMove(src, dest, (long) *src + 1); 
  219. }
  220.  
  221. void    ClearPointer(Ptr p,short s)
  222. /*    ->     p is a pointer and s is the number of bytes to clear out.
  223.         <-    returns nothing.
  224. */
  225. {
  226.     while (s--)
  227.         *p = 0, ++p;
  228. }
  229.  
  230. Boolean CheckError(OSErr    theError, OSErr exceptErr, short errIndex )
  231. /*    ->    theError, exceptErr.  theError that has occures.  Get the appropriate info
  232.                 for this error and report on it.  exceptErr is the exception to the error
  233.                 that we will allow
  234.         <-    Boolean. If the noErr or exceptErr is true then this procedure will return TRUE, else
  235.                 the proc will return false.
  236. */
  237. {    char            *str, *str2;
  238.     short            itemHit;
  239.     
  240.     if ((theError == exceptErr) || (theError == noErr))
  241.          return TRUE;
  242.     GetIndString (str, kStrErr, errIndex);
  243.     NumToString((long)theError, str2);
  244.     ParamText(str, str2, nullStr, nullStr);
  245.     itemHit = Alert(kDialID, NIL);
  246.     return FALSE;
  247. }
  248.  
  249. Ptr FindInitData()
  250. /*    This routine is provided by CE Software. It was published in Inside QuicKeys™ 1.0
  251.         copyright ©1987-88 CE Software. All rights reserved. QuicKeys™ is a trademark of CE Software.
  252.         This routine will search the System Zone for a nonrelocatable block that contains a 
  253.         0xA89F1234 (_Debugger, 0x1234) as the first long word of the block, and kOurCreat, ('flip') as the next one
  254.         in the block.  If it matches, then a pointerto some data is returned. (i.e. the pointer to our global data)
  255.         This allows us to make changes, such as activation key, to our INIT from the cdev without
  256.         having to restart the machine all the time.  Much more convenient!!
  257. */
  258. {
  259.     asm{
  260.             move.l        SysZone,A1                                            ;point A1 at the header
  261.             lea                OFFSET(Zone,heapData)(A1),A0        ;point A0 at the first block
  262.     @0    cmp.l            OFFSET(Zone,bkLim)(A1),A0                ;are we done?
  263.             bge.s            @998
  264.             move.b        (A0),D0                                                    ;see if it's nonrelocatable
  265.             andi.w         #0xC0,D0
  266.             cmp.w            #0x40,D0
  267.             bne.s            @800                                                        ;if not, next block
  268.             move.l        8(A0),D0
  269.             cmp.l            #0xA89F1234,D0
  270.             bne.s            @800
  271.             move.l        12(A0),D0
  272.             cmp.l            #kOurCreat,D0
  273.             bne.s            @800
  274.             move.l        16(A0), D0                    ;return the pointer to the global data
  275.             bra.s            @999
  276.     @800        
  277.             move.l        (A0),D0                        ;point A3 to the next block
  278.             andi.l        #0xFFFFFF,D0            ;strip of header
  279.             add.l            D0,A0                            ;add to A3
  280.             bra.s            @0                                ;and loop back!
  281.     @998                    
  282.             clr.l            D0                                ;search failed, so return false
  283.     @999
  284.     }
  285. }